/************************************************************************/
// Copyright (C) 2016, han_gangbiao. All rights reserved.
// Use of this source code is governed by a GPL-v2 license that can be found in the License file.
// 
// [Time]:      2016-1-4 21:53:17
// [Author]:    han_gangbiao [http://my.oschina.net/jackhen]
// [Info]:      
/************************************************************************/

#include "ppclient.h"

int g_blocksize = 0; //消息块大小
int g_totalCount = 0;//总次数
int g_curCount = 0;  //已经测试的次数

CPPClient::CPPClient(net_reactor_t* pReactorEngine)
    :m_decoder(this)
{
    m_pReactorEngine = pReactorEngine;
	m_cli_fd = -1;
	m_first_time = 0L;
	m_rcv_total_len = 0;
}

CPPClient::~CPPClient()
{
    m_pReactorEngine->close_fd(m_cli_fd);
}

int CPPClient::startConnect(const char* ip, int port)
{
	if(m_pReactorEngine)
		m_cli_fd = m_pReactorEngine->open_tcp_client(ip, port);
	return m_cli_fd;
}

void CPPClient::tag_time_and_count()
{
    m_first_time = smart::mytime_t::getCurrentTimestamp_us(); //us
    g_curCount = 0;
}
int CPPClient::send_pdu(smart::ref_ptr<NetBinaryPdu> pdu)
{
    pdu->toStream();
    //printf("%s\n", pdu->getBody());
    m_pReactorEngine->send(m_cli_fd, pdu->getBinaryStream(), pdu->getBinaryStreamLength());
    return 0;
}


//callback
int CPPClient::on_connect(SOCK_FD listen_fd, SOCK_FD cli_fd, const char* remote_ip, int remote_port)
{
	printf("on_Connect(%d, %s, %d)\n", cli_fd, remote_ip, remote_port);
	return 0;
}

int CPPClient::on_data(SOCK_FD fd, const char* data, int len, const char* remote_ip, int remote_port)
{
    //printf("CPPClient::on_data len=[%d]\n", len);
    m_decoder.Parse(fd, data, len);
	return 0;
}

int CPPClient::on_send_ack(SOCK_FD fd, int len)
{
	return 0;
}

int CPPClient::on_close(SOCK_FD fd, int error)
{
	printf("on_close(%d, %d)\n", fd, error);
	return 0;
}


int CPPClient::onPDU(int fd, smart::ref_ptr<NetBinaryPdu> pdu)
{
    //printf("onPDU\n");
    ++g_curCount;
    if(g_curCount < g_totalCount)
    {//continue ping-pong
        send_pdu(pdu);
        //printf("continue to pdu\n");
    }
    else
    {
    	int64 elapsed = smart::mytime_t::getCurrentTimestamp_us() - m_first_time; //us
        printf("--------------done--------------\n");
        printf("blocksize = %d bytes\n", g_blocksize);
        printf("round-trips = %d\n", g_curCount);
        printf("elapsed = %lld[ms]\n", elapsed/1000);
        printf("%.3f round-trips per second\n", (double)g_curCount * 1000 * 1000 / elapsed);
        printf("%.3f latency[us]\n", (double)elapsed / g_curCount / 2);
        printf("%.3f band width[MB/s]\n", (double)g_blocksize*g_curCount * 1000 * 1000 / elapsed / 1024 / 1024);
    }

    return 0;
}

int CPPClient::onError(int fd, BinaryDecoderError_t err)
{
    return 0;
}


